package com.dongrj.framework.sftp;


import com.google.common.collect.Lists;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

@Slf4j
public final class SftpUtils {


    /**
     * 获取配置创建连接池
     *
     * @param sftpProperties 配置
     */
    public static SftpPool getSftpPool(SftpProperties sftpProperties) {
        SftpFactory sftpFactory = new SftpFactory(sftpProperties);
        return new SftpPool(sftpFactory);
    }


    /**
     * 关闭Sftp链接
     */
    public static void close(ChannelSftp channelSftp) {
        if (channelSftp != null) {
            Session session = null;
            try {
                session = channelSftp.getSession();
            } catch (JSchException e) {
                e.printStackTrace();
                log.error("获取Session异常!", e);
            }
            if (channelSftp.isConnected()) {
                channelSftp.disconnect();
            }
            if (session != null) {
                if (session.isConnected()) {
                    session.disconnect();
                }
            }
        }
    }


    /**
     * 获取远程目录下的文件路径
     *
     * @param pool    连接池
     * @param dirPath 远程目录
     */
    public static List<String> listFile(SftpPool pool, String dirPath) {
        ChannelSftp channelSftp = null;
        List<String> filePathList = Lists.newArrayList();
        try {
            channelSftp = pool.borrowObject();
            Vector ls = channelSftp.ls(dirPath);
            Iterator iterator = ls.iterator();
            while (iterator.hasNext()) {
                ChannelSftp.LsEntry next = (ChannelSftp.LsEntry) iterator.next();
                String filename = next.getFilename();
                Path path = Paths.get(dirPath, filename);
                filePathList.add(path.toString());
            }
            return filePathList;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取文件列表失败，请先检查远程路径是否存在:{}", dirPath, e);
        } finally {
            pool.returnObject(channelSftp);
        }
        return filePathList;
    }


    /**
     * 下载文件
     *
     * @param pool       链接池
     * @param remoteFile 远程文件
     * @param localFile  本地文件
     */
    public static boolean download(SftpPool pool, File remoteFile, File localFile) {
        return download(false, pool, remoteFile, localFile);
    }

    /**
     * 下载文件
     *
     * @param reDownload 本地存在是否重新下载
     * @param pool       链接池
     * @param remoteFile 远程文件
     * @param localFile  本地文件
     */
    public static boolean download(boolean reDownload, SftpPool pool, File remoteFile, File localFile) {
        if (!reDownload) {
            if (localFile.exists()) {
                log.warn("本地文件已存在视作下载成功!:{},{}", remoteFile, localFile);
                return true;
            }
        }
        String parent = localFile.getParent();
        File file = new File(parent);
        if (!file.exists()) {
            log.error("本地目录:{}不存在，请先创建，下载失败!", parent);
            return false;
        }
        ChannelSftp channelSftp = null;
        try {
            log.info("Star download {} to {}", remoteFile, localFile);
            channelSftp = pool.borrowObject();
            channelSftp.get(remoteFile.getAbsolutePath(), localFile.getAbsolutePath());
            log.info("Success download {} to {}", remoteFile, localFile);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("Fail download {} to {}", remoteFile, localFile, e);
        } finally {
            pool.returnObject(channelSftp);
        }
        return false;
    }
}
